package com.cskaoyan.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.cskaoyan.mall.commons.exception.ValidateException;
import com.cskaoyan.user.constants.UserRetCode;
import com.cskaoyan.user.dal.entitys.Member;
import com.cskaoyan.user.dal.entitys.UserVerify;
import com.cskaoyan.user.dal.persistence.MemberMapper;
import com.cskaoyan.user.dal.persistence.UserVerifyMapper;
import com.cskaoyan.user.form.UserRegisterRequest;
import com.cskaoyan.user.form.UserVerifyRequest;
import com.cskaoyan.user.service.IUserRegisterService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @Author:ZhouXin
 * @Date:2022/10/25 21:22
 * @Description:
 **/
@Service
@Slf4j
public class IUserRegisterServiceImpl implements IUserRegisterService {
    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private UserVerifyMapper userVerifyMapper;

    @Autowired
    JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    String mailUsername;
    @Value("${email.text}")
    String mailUrl;
    /**
     * 用户注册
     * 表中的username,phone,email已经做了校验，不能重复了
     * @param request
     */
    @Override
    @Transactional
    public void register(UserRegisterRequest request) {

        //验证用户名是否重复
        voidUserNameRepeat(request);

        //验证邮件是否重复
        voidUserEmailRepeat(request);

        //向用户表中插入一条记录
        Member member = new Member();
        member.setUsername(request.getUserName());
        member.setEmail(request.getEmail());
        //password  要加密，采用spring内置的MD5进行加密
        String userPassword = DigestUtils.md5DigestAsHex(request.getUserPwd().getBytes());
        member.setPassword(userPassword);
        member.setCreated(new Date());
        member.setUpdated(new Date());
        member.setIsVerified("N");
        member.setState(1);

        int affectRows = memberMapper.insert(member);
        if (affectRows != 1) {
            throw new ValidateException(UserRetCode.USER_REGISTER_FAILED.getCode(), UserRetCode.USER_REGISTER_FAILED.getMessage());
        }

        //向用户验证表中插入一条记录
        UserVerify userVerify = new UserVerify();
        userVerify.setUsername(member.getUsername());
        // 生成唯一的uuid
        String key = member.getUsername() + member.getPassword() + UUID.randomUUID().toString();
        String uuid = DigestUtils.md5DigestAsHex(key.getBytes());
        userVerify.setUuid(uuid);
        userVerify.setRegisterDate(new Date());
        userVerify.setIsVerify("N");
        userVerify.setIsExpire("N");
        int rows = userVerifyMapper.insertSelective(userVerify);
        if (rows != 1) {
            throw new ValidateException(UserRetCode.USER_REGISTER_FAILED.getCode(), UserRetCode.USER_REGISTER_FAILED.getMessage());
        }

        //发送用户激活邮件
        //TODO 发送用户激活邮件,激活邮件应该是一个连接，有一个接口去处理我们的用户激活
        sendEmail(uuid, request);

        //打印日志
        log.info("用户注册成功，注册参数request:{}", JSON.toJSON(request));
    }

    /**
     * 验证邮件是否重复
     * @param request
     */
    private void voidUserEmailRepeat(UserRegisterRequest request) {
        Example example = new Example(Member.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("email", request.getEmail());
        List<Member> members = memberMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(members)) {
            throw new ValidateException(UserRetCode.USEEMAIL_ALREADY_EXISTS.getCode(), UserRetCode.USEEMAIL_ALREADY_EXISTS.getMessage());
        }
    }

    /**
     * 发送用户激活邮件
     *
     * @param uuid
     * @param request
     */
    private void sendEmail(String uuid, UserRegisterRequest request) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                SimpleMailMessage message = new SimpleMailMessage();

                message.setSubject("CSMALL用户激活");
                message.setFrom(mailUsername);
                message.setTo(request.getEmail());
//                StringBuilder stringBuilder = new StringBuilder();
//                stringBuilder.append("http://localhost:8080/user/verify?uid=").append(uuid).append("&username=").append(request.getUserName());
//                message.setText(stringBuilder.toString());
                message.setText(String.format(mailUrl,request.getUserName(),uuid));

                mailSender.send(message);
            }
        }).start();
    }

    /**
     * 验证用户名是否重复
     *
     * @param request
     */
    private void voidUserNameRepeat(UserRegisterRequest request) {
        Example example = new Example(Member.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("username", request.getUserName());
        List<Member> members = memberMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(members)) {
            throw new ValidateException(UserRetCode.USERNAME_ALREADY_EXISTS.getCode(), UserRetCode.USERNAME_ALREADY_EXISTS.getMessage());
        }
    }

    /**
     * 用户激活
     *
     * @param request
     */
    @Override
    public void verify(UserVerifyRequest request) {
        //用户验证，修改用户表
        //根据username,修改验证表中的状态
        UserVerify userVerify = new UserVerify();
        userVerify.setIsVerify("Y");
        Example example = new Example(UserVerify.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("username", request.getUsername());
        int affectRows = userVerifyMapper.updateByExampleSelective(userVerify, example);
        if (affectRows != 1) {
            throw new ValidateException(UserRetCode.USER_INFOR_INVALID.getCode(), UserRetCode.USER_INFOR_INVALID.getMessage());
        }
        //修改member表中的isverified
        Member member = new Member();
        member.setIsVerified("Y");
        Example memberExample = new Example(Member.class);
        Example.Criteria memberExampleCriteria = memberExample.createCriteria();
        memberExampleCriteria.andEqualTo("username",request.getUsername());
        int effectRows = memberMapper.updateByExampleSelective(member, memberExample);
        if (effectRows != 1) {
            throw new ValidateException(UserRetCode.USER_INFOR_INVALID.getCode(), UserRetCode.USER_INFOR_INVALID.getMessage());
        }
    }
}
